package org.lw.aop.aspect;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;

import java.lang.reflect.Array;
import java.util.Arrays;

@Aspect
@Component
public class LoggingAspect {//切面
    @Before("pointCut()")//切入点:定义通知执行的地点，@Before代表在方法执行之前执行
    public void before(JoinPoint joinPoint) {//通知
        System.out.println("方法：" + joinPoint.getSignature().getName() + "开始执行，参数是：" + Arrays.toString(joinPoint.getArgs())); //连接点
    }
    @After("execution(public * org.lw.aop.service.impl.MyCaculator.*(..))")
    public void after(JoinPoint joinPoint) {
        System.out.println("方法：" + joinPoint.getSignature().getName() + "最终结束");
    }
    @AfterThrowing("execution(public * org.lw.aop.service.impl.MyCaculator.*(..))")
    public void afterThrowing(JoinPoint joinPoint) {
        System.out.println("方法：" + joinPoint.getSignature().getName() + "异常结束");
    }
    @AfterReturning("execution(public * org.lw.aop.service.impl.MyCaculator.*(..))")
    public void afterReturning(JoinPoint joinPoint) {
        System.out.println("方法：" + joinPoint.getSignature().getName() + "正常结束");
    }
    public void around() {
        System.out.println("around......");
    }
    @Pointcut("execution(public * org.lw.aop.service.impl.MyCaculator.*(..))")
    public void pointCut() {
    }
}
/*
*      AOP的术语
*         1.切面（Aspect）：横切关注点被模块化的特殊对象，即它是一个类
*         2.连接点（Joinpoint）：程序执行过程中明确的点，如方法的调用或特定的异常被抛出
*         3.通知（Advice）：切面要完成的工作，即在连接点上执行的动作
*         4.切入点（Pointcut）：切面通知执行的地点，即连接点的定义
*         5.目标对象（Target Object）：被一个或多个切面通知的对象
*         6.织入（Weaving）：将切面连接到目标对象并创建通知对象的过程
*      Aop的实现方式
          1、将切面加载到IOC容器中
          2、使用@Aspect注解将一个java类定义为切面
          3、使用@Pointcut注解定义切入点
          4、使用通知注解定义通知
          * @Before：前置通知，在方法执行之前执行
          * @After：后置通知，在方法执行之后执行
          * @AfterReturning：返回通知，在方法返回结果之后执行
          5、在配置类中开启AspectJ的自动代理
          * @EnableAspectJAutoProxy
          6、在测试类中使用@AutoWired注解注入代理对象
          * @AutoWired
            此时注入的是代理对象，而不是目标对象。
            代理对象是由Spring容器创建的，它是目标对象的代理对象，它会拦截目标对象的方法调用，从而实现AOP的功能。
       Aop的原理
       * 1、Spring容器会为目标对象创建代理对象
       * 2、代理对象会拦截目标对象的方法调用
       * 3、在方法调用前后执行通知
       * 4、通知的执行顺序
       * 5、通知的参数
       * * JoinPoint：连接点，表示目标对象的方法
       * * JoinPoint.getSignature()：获取方法签名
       * * JoinPoint.getArgs()：获取方法参数
       * 6、通知的类型
       * 7、切入点表达式
       * * execution(public * org.lw.aop.service.impl.MyCaculator.*(..))
       * * execution：表达式的固定写法
       * * public：方法的修饰符
       * * *：返回值类型，*表示任意类型
       * * org.lw.aop.service.impl.MyCaculator：目标对象的类名
       * * *：方法名，*表示任意方法
       * * (..)：方法参数，..表示任意参数
       * 8、切入点表达式的使用
       * * 在通知注解中使用
       * * 在@Pointcut注解中使用
       *

*
*
* */
